<script setup>
import util from '@/utils/util'
import {Role, Permission} from '@/utils/resource'
import {confirm, showSaveResponse, validFieldExists, validateForm} from '@/utils/element-helper'
import {roleStore} from "@/store/role";
import {nextTick, ref, reactive} from "vue";
import {ElMessage} from "element-plus";
import {permissionStore} from "@/store/perminnion";

const roleStoreS = roleStore()
const permissionStoreS = permissionStore()
const queryParamsLoading = ref(false)
const tree = ref(null)
const editRoleForm = ref(null)
const roleState = reactive({
  table: {
    rows: [],
    total: 0,
    pageSize: 10,
    pageNumber: 1,
    loading: false,
  },
  currentRole: {},
  editRole: {},
  isNew: true,
  dialogVisible: false,
  rules: {
    name: [
      {required: true, message: '角色名称不能为空', trigger: 'blur'},
      {
        validator, trigger: 'blur'
      }
    ],
  },
  async queryRoles() {
    if (roleStoreS.queryParams.name === "" || roleStoreS.queryParams.name == null) {
      delete roleStoreS.queryParams["name"]
    }
    queryParamsLoading.value = true
    await Role.search(roleState.table, {
      sc: [
        {
          "condition": "and",
          "comparator": "like",
          "field": "description,name",
          "value": roleStoreS.queryParams.name
        },
        {
          "condition": "by",
          "comparator": "order by",
          "field": 'id',
          "value": "asc"
        }
      ],
    })
    roleState.table.rows.push({
      id: undefined,
      name: '新增角色',
      description: "",
      icon: "CirclePlus",
    })
    roleState.currentRole = {}
    await nextTick()
    queryParamsLoading.value = false
  },
  handleRowClick(row, event, column) {
    //选中角色行
    if (row.id !== undefined && row.name !== '新增角色') {
      roleState.currentRole = row
      roleTreeState.loadRolePermissions()
    } else {
      roleState.handleAddRole();
    }
  },
  handleAddRole() {
    //新增角色
    roleState.dialogVisible = true
    roleState.currentRole = {}
    roleState.editRole = {}
    roleState.clearRoleForm()
    roleState.isNew = true
  },
  async clearRoleForm() {
    editRoleForm.value.clearValidate()
  },

  handleEditRoleDialogConfirm(formName) {
    return validateForm(editRoleForm.value, formName, () => {
      roleState.loading = true
      showSaveResponse(roleState.loading,
          () => Role.save(roleState.editRole, roleState.isNew ? 'post' : 'put'),
          (res) => {
            roleState.queryRoles()
            roleState.dialogVisible = false
            roleState.loading = false
          },
          () => roleState.loading = false)
    })
  },
  handleRoleEdit(id, row) {
    roleState.dialogVisible = true
    roleState.currentRole = util.copy(row)
    roleState.editRole = util.copy(row)
    roleState.clearRoleForm()
    roleState.isNew = false
  },
  handleRoleDelete(id, row) {
    confirm({}, () => Role.del(row.id), (resp) => roleState.queryRoles())
  },
  async handlePermissionChange() {
    if (roleState.currentRole.id === undefined) {
      ElMessage.error('请在左侧列表选择角色!');
      return
    }
    let tempFrom = {
      roleId: roleState.currentRole.id,
      permissionIds: tree.value.getCheckedKeys()
    }
    //添加父节点
    tempFrom.permissionIds = tempFrom.permissionIds.concat(tree.value.getHalfCheckedKeys())
    roleTreeState.loading = true
    showSaveResponse(undefined, () => Role.updateRolePermissions(tempFrom))
    roleTreeState.loading = false
  },
})


function validator(rule, value, callback) {
  validFieldExists(rule, value, callback, roleState.currentRole[rule.field] !== value || roleState.isNew, (rule, value) => Role.exists(rule, value))
}

const roleTreeState = reactive({
  loading: true,
  collapseFlag: false,
  roleData: [],
  rolePermissionArray: [],
  checkedRolePermissionData: [1],
  async loadPermissions() {
    roleTreeState.loading = true
    let res = await Permission.tree()
    await permissionStoreS.loadPermissions()
    await nextTick()
    roleTreeState.loading = false
  },
  async loadRolePermissions() {
    if (roleState.currentRole.name === '系统管理员') {
      roleTreeState.disableTreeToggle(true)
    } else {
      roleTreeState.disableTreeToggle(false)
    }
    roleTreeState.loading = true
    let res = await Role.rolePermission(roleState.currentRole.name)
    let checkedAr = res.data.map(d => d.id)
    roleTreeState.checkedRolePermissionData = checkedAr
    tree.value.setCheckedKeys(checkedAr)
    await nextTick()
    roleTreeState.loading = false
  },
  //展开收起所有树节点
  handleTreeToggle(data) {
    let nodes = tree.value.store._getAllNodes();
    for (let i = 0; i < nodes.length; i++) {
      nodes[i].expanded = data;
    }
  },
  disableTreeToggle(data) {
    let nodes = permissionStoreS.permissionsArray;
    for (let i = 0; i < nodes.length; i++) {
      nodes[i].disabled = data ? 'disabled' : '';
    }
  },
})
roleState.queryRoles()
roleTreeState.loadPermissions()

</script>

<template>
  <el-row>
    <el-col :xs="24" :span="6" style="padding: 0 10px 10px 0">
      <el-card :body-style="{minHeight: '300px'}">
        <el-row>
          <el-input
              placeholder="回车查询角色"
              clearable
              @keyup.enter.native="roleState.queryRoles"
              v-model="roleStoreS.queryParams.name">
            <template #suffix>
              <el-icon class="el-input__icon">
                <component is="Search"></component>
              </el-icon>
            </template>
          </el-input>
        </el-row>
        <el-row>
          <el-table v-loading="queryParamsLoading"
                    :data="roleState.table.rows"
                    style="width: 100%"
                    @row-click="roleState.handleRowClick"
                    :highlight-current-row="true">
            <el-table-column
                prop="name"
                label="角色列表"
                align="left">
              <template #default="scope">
                <div class="row-role-name" :class="scope.row.icon==='CirclePlus'?'row-blue':''">
                  <div class="flex-center">
                    <el-icon>
                      <component :is="scope.row.icon"></component>
                    </el-icon>
                    <div class="text">{{ scope.row.name }}</div>
                  </div>
                </div>
                <div style="float: right" v-show="scope.row.icon!=='CirclePlus'">
                  <a v-show="scope.row.id!==-1" class="mimi-icon"
                     @click.stop="roleState.handleRoleEdit(scope.row.id,scope.row)"
                     title="编辑">
                    <el-icon>
                      <component is="Edit"></component>
                    </el-icon>
                  </a>&nbsp;
                  <a v-show="scope.row.id!==-1 && scope.row.id!==86" class="mimi-icon"
                     @click.stop="roleState.handleRoleDelete(scope.row.id,scope.row)"
                     title="删除">
                    <el-icon>
                      <component is="Delete"></component>
                    </el-icon>
                  </a>
                </div>
              </template>
            </el-table-column>
          </el-table>
          <div class="bottom-area"></div>
        </el-row>
      </el-card>

      <el-dialog
          title="角色详情"
          v-model="roleState.dialogVisible"
          width="30%">
        <el-form :model="roleState.editRole" label-position="left" :rules="roleState.rules" ref="editRoleForm">
          <el-form-item label="" prop="name">
            <el-input v-model="roleState.editRole.name" placeholder="角色名称"></el-input>
          </el-form-item>
          <el-form-item label="" prop="description">
            <el-input type="textarea" :rows="2" v-model="roleState.editRole.description" placeholder="角色描述"></el-input>
          </el-form-item>
          <p style="color: #909399">角色名称全局不能重复</p>
        </el-form>
        <span slot="footer" class="dialog-footer">
        <el-button :loading="roleState.loading" type="danger" @click="roleState.handleEditRoleDialogConfirm('editRole')"
                   style="width: 100%">确 定</el-button>
        </span>
      </el-dialog>
    </el-col>
    <el-col :xs="24" :span="18" style="padding: 0 10px 10px 0">
      <el-card :body-style="{minHeight: '300px'}">
        <el-row>
          <el-col :span="12">
            <div style="color: #909399" v-if="roleState.currentRole.name!==undefined">
              {{ roleState.currentRole.name }}<span
                style="color: #99a9bf; font-size: 13px;padding-left: 5px"> {{
                roleState.currentRole.description
              }}</span></div>
            <div style="color: #909399" v-else>没有角色被选中</div>
          </el-col>

          <el-col :span="12">
            <div>
              <div style="float: right;">
                <el-button :disabled="roleState.currentRole.id===-1" type="primary" plain size="small"
                           @click="roleState.handlePermissionChange"
                           icon="Upload"
                           style="width: 100%">保存修改</el-button>
              </div>
              <div style="float: right;margin-right: 10px;margin-top: 2px;">
                <el-switch
                    v-model="roleTreeState.collapseFlag"
                    active-color="#67C23A"
                    inactive-color="#F56C6C"
                    @change="roleTreeState.handleTreeToggle">
                </el-switch>
                <span style="color: #606266;font-size: 14px;">&nbsp;{{
                    roleTreeState.collapseFlag ? '已展开' : '已收起'
                  }}</span>
              </div>
            </div>
          </el-col>
        </el-row>
        <el-divider></el-divider>
        <el-row style="padding: 15px" v-loading="roleTreeState.loading">
          <el-tree
              :data="permissionStoreS.permissionsTree"
              show-checkbox
              highlight-current
              node-key="id"
              ref="tree"
              :check-strictly="true"
              :props="{children: 'children', label: 'name'}">
            <template #default="{ node, data }">
              <span class="custom-tree-node">
                <el-icon class="el-input__icon">
                  <component :is="data.icon"></component>
                </el-icon>
              {{ data.name }}
              </span>
            </template>
          </el-tree>
        </el-row>
      </el-card>
    </el-col>
  </el-row>


</template>

<style scoped lang="scss">
.row-role-name {
  font-size: 16px;
  cursor: pointer;
  float: left;

  .text {
    padding-left: 5px;
  }
}

.row-blue {
  color: #42A1FF;
}

.bottom-area {
  height: 25px;
}

.mimi-icon {
  cursor: pointer;
}

.custom-tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  font-size: 14px;
  padding-right: 8px;
}
</style>
